﻿using Autofac;
using Microsoft.EntityFrameworkCore;
using XsqTech.SmartOA.Application.ServiceExtensions;
using XsqTech.SmartOA.EFCore;
using XsqTech.SmartOA.EFCore.Respository;
using XsqTech.SmartOA.EFCore.Respository.Base;
using XsqTech.SmartOA.Infrastructure.JWT;
using XsqTech.SmartOA.Service.ConfigAutoMapper;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
//配置Swagger显示中文注释
builder.Services.AddSwaggerSetup();

//注册AutoMapper服务
builder.Services.AddAutoMapper(typeof(configAutoMapper));
//在startup.cs 里边， ConfigureService()里边进行注册
builder.Services.AddControllers(options =>
{
    //添加全局异常过滤器
    options.Filters.Add<XsqTech.SmartOA.Infrastructure.Filter.GlobalExceptionFilter>();
    //Action过滤器
    options.Filters.Add<XsqTech.SmartOA.Infrastructure.Filter.GlobalActionFilter>();
    //授权过滤器
    //options.Filters.Add<XsqTech.SmartOA.Application.Auth.PermissionAuthorizeFilter>();

});

#region 注册Jwt
//builder.Services.AddSwaggerGen(c =>
//{
//    //启用swagger验证功能
//    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
//    {
//        Description = "在下框中输入请求头中需要添加Jwt授权Token：Bearer Token",
//        Name = "Authorization",//jwt默认的参数名称
//        In = ParameterLocation.Header,//jwt默认存放authorization信息的位置(请求头中)
//        Type = SecuritySchemeType.ApiKey,
//        BearerFormat = "JWT",
//        Scheme = "Bearer"
//    });
//    //添加全局安全条件
//    c.AddSecurityRequirement(new OpenApiSecurityRequirement
//{
//    {
//        new OpenApiSecurityScheme {
//            Reference = new OpenApiReference {
//                Type = ReferenceType.SecurityScheme,
//                Id = "Bearer" }
//        }, new string[] { }
//    }
//});
//});

//JWTTokenOptions JWTTokenOptionss = new JWTTokenOptions();
////获取appsettings的内容
//builder.Services.Configure<JWTTokenOptions>(builder.Configuration.GetSection("JWTToken"));
////将给定的对象实例绑定到指定的配置节
//builder.Configuration.Bind("JWTToken", JWTTokenOptionss);
////注册到Ioc容器
//builder.Services.AddSingleton(JWTTokenOptionss);
////【授权】
//builder.Services.AddAuthorization(options =>
//{
//    options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
//    options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
//    options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
//});
////添加验证服务
//builder.Services.AddAuthentication(option =>
//{
//    //默认身份验证模式
//    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
//    //默认方案
//    option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
//    option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
//}).AddJwtBearer(option =>
//     {
//         //设置元数据地址或权限是否需要HTTP
//         option.RequireHttpsMetadata = false;
//         option.SaveToken = true;
//         //令牌验证参数
//         option.TokenValidationParameters = new TokenValidationParameters
//         {
//             ValidateIssuerSigningKey = true,
//             //获取或设置要使用的Microsoft.IdentityModel.Tokens.SecurityKey用于签名验证。
//             IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.
//             GetBytes(JWTTokenOptionss.Secret)),
//             //获取或设置一个System.String，它表示将使用的有效发行者检查代币的发行者。 
//             ValidIssuer = JWTTokenOptionss.Issuer,
//             //获取或设置一个字符串，该字符串表示将用于检查的有效受众反对令牌的观众。
//             ValidAudience = JWTTokenOptionss.Audience,
//             //是否验证发起人
//             ValidateIssuer = false,
//             //是否验证订阅者
//             ValidateAudience = false,
//             //允许的服务器时间偏移量
//             ClockSkew = TimeSpan.Zero,
//             //是否验证Token有效期，使用当前时间与Token的Claims中的NotBefore和Expires对比
//             ValidateLifetime = true
//         };
//         //如果jwt过期，在返回的header中加入Token-Expired字段为true，前端在获取返回header时判断
//         option.Events = new JwtBearerEvents()
//         {
//             OnAuthenticationFailed = context =>
//             {
//                 if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
//                 {
//                     context.Response.Headers.Add("Token-Expired", "true");
//                 }
//                 return Task.CompletedTask;
//             }
//         };
//     });
#endregion

//获取jwt配置项
var jwtTokenConfig =
builder.Configuration.GetSection("JWTTokenOption").Get<JwtTokenOption>();
builder.Services.AddSingleton(jwtTokenConfig); //注册单例服务，以便后续调用
builder.Services.AddJWTSetup(jwtTokenConfig);
builder.Services.AddControllers();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

//用扩展方法
builder.Services.AddCorsSetup(builder.Configuration["CorrsIps"].Split(","));
//跨域
builder.Services.AddDbContext<DbContext, MyDbContext>(x =>
{
    x.UseSqlServer(builder.Configuration.GetConnectionString("conn"));
});

//定时任务
//builder.Services.AddHostedService<SendMessageJob>();

#region 注册Autofac
//注册Autofac
builder.Host.UseServiceProviderFactory(new Autofac.Extensions.DependencyInjection.AutofacServiceProviderFactory());//注册Autofac容器，不注册就用不了
builder.Host.ConfigureContainer<Autofac.ContainerBuilder>(b =>
{
    b.RegisterModule<XsqTech.SmartOA.Application.ConfigAutofac>();
});
#endregion

//注入工作单元
builder.Services.AddScoped<IUnitOfWork, UnitOfWork<MyDbContext>>();

var app = builder.Build();

#region
//app.Use((cxt, next) =>
//{
//    Console.WriteLine("use请求委托");
//    return next();//掉用下一个委托
//});
////我们要写一个方法，然后赋值给一个请求委托对象（requestHandler）
//app.Run(ctr =>
//{
//    Console.WriteLine("用了中间件");
//    return Task.FromResult(1000);
//}
//    );

#endregion

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

//跨域中间件
app.UseCors();

app.MapControllers();//控制器里面是专注于我们业务系统的业务功能，其他的事情交给，过滤器，中间件

//自定义中间件，记录请求花了多少时间
//app.UseRequestLogMiddleware();

//启用身份验证中间件
app.UseAuthentication();

//授权中间件
app.UseAuthorization();

app.Run();

